package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.LinkedList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;


public class Query {
	
	//Nuestra AppID es:270402DA15BEAF2C6C7CDFFA783BD31EEC8F892E
	private String appId;
		
	public Query(){
		this.appId = "270402DA15BEAF2C6C7CDFFA783BD31EEC8F892E";
	}
	
	/*
	 * Metodos de busqueda en Microsoft Academic Search
	 */
	
	/*0. Metodo generico que realiza las consultas a la web*/
	private String executeQuery(String web){
		String resultado = "";
		try {
		    // Crear la URL
		    URL url = new URL(web);
		    // Leer todo el texto devuelto por el servidor
		    BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
		    String str;
		    while ((str = in.readLine()) != null) {
		        // str es una linea de texto
		    	resultado = str;
		    	
		    }
		    in.close();
		} catch (MalformedURLException e) {
		} catch (IOException e) {
		}
		
		return resultado;
	}
	
	/*A.Metodo que usa dos ya hechos para encadenarlos*/
	public Integer getNumberOfCites(String articleTitle){
		Integer i = -1;
		if(isArticleFound(articleTitle)){
		String id = getArticleID(articleTitle);
		i = new Integer(getCites(id));
		}
		return i;
	}
	
	public List<TwoValues> getRelatedArticles(String articleTitle){
		List<TwoValues> list = new LinkedList<TwoValues>();
		list.add(new TwoValues("null", "null"));
		if(isArticleFound(articleTitle)){
			String id = getArticleID(articleTitle);
			list = getRelated(id);
		}
		return list;
	}
	

	/*1. Obtener la id de un articulo segun el resultado de una busqueda de texto*/
	private String getArticleID(String query){
		String end="";
		
		//Convertimos los espacios es caracteres validos para la busqueda
		String q = Funciones.espaciosBusqueda(query);
		
		//Sentencia de busqueda
		String request = executeQuery("http://academic.research.microsoft.com/json.svc/search?AppId="+appId+"&FullTextQuery=" +
				q+"&ResultObjects=Publication&PublicationContent=AllInfo&StartIdx=1&EndIdx=10");
	
		try {
			
			JSONObject objeto = new JSONObject(request);
			JSONObject d = new JSONObject(objeto.get("d").toString());
			JSONObject publication = new JSONObject(d.get("Publication").toString());
			JSONArray result = new JSONArray((publication.getString("Result")));
			JSONObject element = new JSONObject(result.getString(0));
			end = element.getString("ID");
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return end;
	}

	
	
	/*2. Devolver el numero de citas de una publicacion buscando por su ID*/
	private String getCites(String articleId){
		String request = executeQuery("http://academic.research.microsoft.com/json.svc/search?AppId="+appId+"&PublicationID=" +
				articleId+"&ResultObjects=Publication&ReferenceType=Citation&StartIdx=1&EndIdx=1&OrderBy=Year"); 
		
		String result=null;
		try {
			JSONObject objeto = new JSONObject(request);
			JSONObject d = new JSONObject(objeto.get("d").toString());
			JSONObject publication = new JSONObject(d.get("Publication").toString());
			result = (publication.get("TotalItem")).toString();
		} catch (ParseException e) {
			
			e.printStackTrace();
		}
		
		return result;

	}
	
	
	
	/*3. Este devuelve un listado de articulos que han publicado a una publicacion suministrada por su ID*/
	private List<TwoValues> getRelated(String articleId){
		List<TwoValues> list = new LinkedList<TwoValues>();
		
		String request = executeQuery("http://academic.research.microsoft.com/json.svc/search?AppId="+appId+"&PublicationID=" +
				articleId+"&ResultObjects=Publication&ReferenceType=Citation&StartIdx=1&EndIdx=50&OrderBy=Year"); 
	
		
		try {
			JSONObject objeto = new JSONObject(request);
			JSONObject d = new JSONObject(objeto.getString("d"));
			JSONObject publication = new JSONObject(d.getString("Publication"));
			JSONArray result = new JSONArray((publication.getString("Result")));
			Integer totalItem = new Integer((publication.getString("TotalItem")));
			
			//Recorremos el array para obtener todos los articulos
			for (int i=0;i<totalItem;i++){
				JSONObject element = new JSONObject(result.getString(i));
				String id = element.getString("ID");
				String title = element.getString("Title");
				list.add(new TwoValues(id, title));
			}
			
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		return list;
	}
	
	
	/*4.Controla si el articulo se encuentra en la BD de MAS*/
	public Boolean isArticleFound(String query){
		String q = Funciones.espaciosBusqueda(query);
		Boolean b = true;
		String request = executeQuery("http://academic.research.microsoft.com/json.svc/search?AppId="+appId+"&FullTextQuery=" +
				""+q+"&ResultObjects=Publication&PublicationContent=AllInfo&StartIdx=1&EndIdx=10");
		
		try {
			JSONObject objeto = new JSONObject(request);
			JSONObject d = new JSONObject(objeto.get("d").toString());
			JSONObject publication = new JSONObject(d.get("Publication").toString());
			int totalItem = new Integer((publication.get("TotalItem")).toString());
			if (totalItem == 0){
				b = false;
			}
			
		} catch (ParseException e) {
			
			e.printStackTrace();
		}
		return b;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	//Este es un buscador de publicaciones por texto libre
	private String freePublicationSearch(String query){
		String q = Funciones.espaciosBusqueda(query);
		return executeQuery("http://academic.research.microsoft.com/json.svc/search?AppId="+appId+"&FullTextQuery=" +
				""+q+"&ResultObjects=Publication&PublicationContent=AllInfo&StartIdx=1&EndIdx=10");
		
		
		
	}
	
	
	
	
	
	
		//Este es un metodo de pruebas
		private String prueba(String query){
			String q = Funciones.espaciosBusqueda(query);
			return executeQuery("http://academic.research.microsoft.com/json.svc/search?AppId="+appId+"&PublicationID=" +
					q+"&ResultObjects=Publication&ReferenceType=Citation&StartIdx=1&EndIdx=1&OrderBy=Year");
		}
		
		
}
